home *** CD-ROM | disk | FTP | other *** search
- #!/usr/local/bin/perl
- #
- # gee - gopher environment editor (Beta Test Version)
- # copyright (c) Bill Middleton, 1993 - all rights reserved
- # wjm@feenix.metronet.com
- #
- # Absolutely No Warranty expressed or implied. Use with care.
- # Send comments, suggestions, and fixes to me please.
- #
- # Initial improvements suggested by Randy Bush, randy@psg.com
- # More help from moose@sunet.se, and jdc@selway.umt.edu.
- # Many thanks to these and others who have sent commentary.
- # To get on the discussion list, drop me a line here at feenix.
- #
-
- require ("ctime.pl");
-
- # Configure Here for your site/preferences
-
- $toplevel='/usr/pub/'; # make this your toplevel gopher dir
- $thishost='feenix.metronet.com'; # make this your host
- $plen = 19; # this page length works for 23-24 line terms
- $ed='/usr/bin/vi'; # or whatever
- $pager='/usr/local/bin/less'; # or whatever
- $mv='/bin/mv'; # path to mv
- $cp='/bin/cp'; # how we copy
- $rm='/bin/rm -i'; # safe rm
- $ln='/bin/ln '; # how we link (symlink default)
- $def_port=70; # default port
- $using_dir_list=0; # set this if using list of directories
- $dirfilename="./gopherdirs"; # file with list of directories (see getdirs)
- $names='.names'; # default .link file
-
- if($using_dir_list){
- require ("win.pl"); # and an ansi knowledgable term
- }
- # End configure
- #
- # get some user stuff
- (defined $ENV{'EDITOR'}) && ($ed = $ENV{'EDITOR'});
- (defined $ENV{'PAGER'})&&($pager = $ENV{'PAGER'});
-
- system("clear");
- @stack='';
- $dir='.';
- print "Welcome GopherMeister...\n";
- if($using_dir_list){
- open(DIRS,"<$dirfilename")||die "cant open";
- while(<DIRS>){
- chop;$dirs{$_}=1;
- }
- close(DIRS);
- print "Select starting directory? (y|n) > ";
- $ans=<STDIN>;
- $ans=~/^[Yy]/ && ($firstdir=1);
- if($firstdir){
- $firstdir=&select_dir;
- $firstdir=~s/^\/(.*)\/?$/$1/;
- @stack=split('/',$firstdir);
- }
- }
-
- while($dir ne 'last'){
- %files=%links=%caps=%cache=%all=();
- ($dir eq "..") ? pop(@stack):(($dir ne '.') && push(@stack,$dir));
- $realdir=$toplevel.join('/',@stack);
- $realdir=~s#(/)/#$1#;
- if(!(-d "$realdir")){
- print "Bad directory selection, returning to toplevel\n";
- $realdir=$toplevel;
- @stack=("");
- }
- chdir $realdir || die "real trouble\n";
- $dir=&read_em;
- }
-
-
- sub bygroup{
- local($namea,$typea,$patha,$hosta,$porta,$numba,$statusa)=split('#,#',$all{$a});
- local($nameb,$typeb,$pathb,$hostb,$portb,$numbb,$statusb)=split('#,#',$all{$b});
- if($numba < $numbb){
- return -1;
- }elsif($numba > $numbb){
- return 1;
- }else{
- if($namea lt $nameb){
- return -1;
- }elsif($namea gt $nameb){
- return 1;
- }else{
- return 0;
- }
- }
- }
-
- sub read_em{
- local($i,$j);
- local($name,$type,$path,$host,$port,$numb,$status);
- local(@parse);
- (-d ".cap") && (%caps = &read_caps);
- %links = &read_links;
- %files = &read_files;
- for (keys(%files)){
- ($name,$type,$path,$host,$port,$numb,$status)=&parsef($_);
- $path=~s/.*\///;
- if(defined($caps{$_})){
- @parse=&parse($caps{$_},$name,$type,$path,$host,$port,$numb,$status);
- $all{$_}=join('#,#',@parse);
- }elsif(defined($links{$_})){
- @parse=&parse($links{$_},$name,$type,$path,$host,$port,$numb,$status);
- $all{$_}=join('#,#',@parse);
- }else{
- $all{$_}=join('#,#',($name,$type,$path,$host,$port,$numb,$status));
- }
- }
- for (keys(%links)){
- next if (defined($all{$_}));
- $type=$path=$host='undefined';
- $name=$_;
- $status="OK";
- @parse=&parse($links{$_},$name,$type,$path,$host,$port,$numb,$status);
- $all{$_}=join('#,#',@parse);
- }
- for (keys(%caps)){
- next if (defined($all{$_}));
- $type=$path=$host='undefined';
- $name=$_;
- $status="OK";
- @parse=&parse($caps{$_},$name,$type,$path,$host,$port,$numb,$status);
- $all{$_}=join('#,#',@parse);
- }
- @keys=sort bygroup keys(%all);
- system "clear";
- for(;;){
- if($i>$plen){
- $l = length($realdir);
- ($l>60) ? ($c_dir=substr($realdir,$l-60)):($c_dir=$realdir);
- print "\ncwd: $c_dir (h for help) > ";
- chop($num=<STDIN>);
- if($num =~ /^[Ff]/){
- $j += ($plen+1) unless ($j>=$#keys);
- }elsif($num =~ /^[Bb]/){
- $j -= ($plen+1) unless ($j<=($plen+1));
- }elsif($num =~ /^\!(.*)/){
- system("$1");
- print " Carriage Return to continue > ";
- chop($num=<STDIN>);
- $dir = '.';
- last;
- }elsif($num =~ /^[Cc]/){
- print "Enter number of directory to change to ";
- if($using_dir_list){
- print ", or a ? to use directory selector > ";
- chop($c=<STDIN>);
- }else{
- print "> ";
- chop($c=<STDIN>);
- }
- if($using_dir_list){
- if($c =~ /^\s*[?]/){
- ($c=&select_dir) && ($c=~s/^\/(.*)\/?$/$1/);
- @stack=split('/',$c);
- $dir='.';
- }else{
- defined($keys[$c]) ? ($dir=$keys[$c]) : ($dir = '.');
- }
- }else{
- defined($keys[$c]) ? ($dir=$keys[$c]) : ($dir = '.');
- }
- last;
- }elsif($num =~ /^[Hh]/){
- &give_a_clue1;
- }elsif($num =~ /^[Dd]/){
- &create_dot_names;
- $dir='.';
- last;
- }elsif($num =~ /[Qq]/){
- $dir='last';
- last;
- }elsif(($num =~/^\d/) && ($num <= $#keys)){
- $num = &view_lead($keys[$num]);
- $dir='.';
- last if $num == -1;
- }
- $j-=($plen+1);
- system "clear";
- $- = 0;
- $i=0; next;
- }else{
- $t="$j>";
- ($j==0 )&&($t='0>');
- if($j > $#keys) {$t=undef;@a=("");}
- else{@a = split('#,#',$all{$keys[$j]});}
- write;
- $i++;$j++;
- }
- }
- $- = 0;
- $dir;
- }
-
- format STDOUT =
- @<<< @<<<<<<<<<<<<<<<<<<<< @| @||||||||||||||| @<<<<<<<<<<<<<< @>>> @||| @>>>>>
- $t,$a[0],$a[1],$a[2],$a[3],$a[4],$a[5],$a[6]
- .
-
- format STDOUT_TOP =
- Num Name Type Path Host Port Numb Status
- -------------------------------------------------------------------------------
- .
-
- sub read_caps{
- local(%tmp,@files);
- # read the .caps files corresponding to the current dir
- opendir(CURDIR,".cap");
- @files = grep(!/^\.\.?$/, readdir(CURDIR));
- $/="";
- for (@files){
- @stat=stat(".cap/$_");
- if((-T _)&&(-r _)&&(-e $_)){
- if(!((($stat[2] >> 6) & 04)&&(($stat[2] >> 3) & 04)&&($stat[2] & 04))){
- $tmp{$_}.=".cap/$_ : not world readable\n";
- }else{
- $tmp{$_}.=".cap/$_: world readable\n";
- }
- open(CAP,"<.cap/$_");
- $entry =<CAP>;
- close CAP;
- $tmp{$_} .= "$entry";
- }else{
- $tmp{".cap/$_"} .= "ERROR in .cap/$_,\n not a regular text file, or not readable,\nor corresponding $_ does not exist\n";
- }
- }
- $/="\n";
- %tmp;
- }
-
- sub read_links{
- local(%tmp,@files,$i);
- local($name,$type,$path,$host,$status);
- # read the .caps files corresponding to the $dir
- opendir(CURDIR,".");
- #@files = grep(/^\..*[LlNn][IiAa][NnMm][KkEe][Ss]?$/, readdir(CURDIR));
- @files = grep(/^\.\w.*$/, readdir(CURDIR));
- $/="";
- $i=1;
- for $f (@files){
- next if ($f eq ".cache");
- next if (-d "./$f");
- if((-T $f)&&(-r $f)){
- open(LINK,"<$f");
- while(<LINK>){
- ($name,$type,$path,$host,$port,$numb,$status)=&parse($_);
- $tmp{$path} ="$f\n$_";
- }
- close(LINK);
- }else{
- $tmp{$f} = "Not a regular .link or .names file,\n or not readable.";
- }
- }
- $/="\n";
- %tmp;
- }
-
- sub read_files{
- local (%tmp);
- local($i);
- local(@files);
- opendir(CURDIR,".");
- @files = grep(!/^\.$/, readdir(CURDIR));
- closedir CURDIR;
- for (@files){
- $tmp{$_}=join('/',grep(/[\S]/,@stack))."/$_";
- @stat=stat($_);
- $r = ((($stat[2] >> 6) & 04)&&(($stat[2] >> 3) & 04)&&($stat[2] & 04));
- $x = ((($stat[2] >> 6) & 01)&&(($stat[2] >> 3) & 01)&&($stat[2] & 01));
- if(-d _){
- $tmp{$_}.=" : Dir";
- (!$x) && ($tmp{$_}.= ": NOT world scannable");
- $tmp{$_}.="\n";
- }
- if(-f _){
- (-T _) ? ($tmp{$_}.=" : Text\n"):($tmp{$_}.=" : NoTxt\n");
- }
- if(!(-r _)){
- $tmp{$_}.="ERROR not readable:";
- }elsif(!$r){
- $tmp{$_}.="Not world readable :";
- }else{
- $tmp{$_}.="World readable :";
- }
- if(-l "$_"){
- $realname=readlink($_);
- $tmp{$_}.=" symlink to $realname\n";
- }elsif((-f _)||(-d _)){
- $tmp{$_}.=" regular file or dir\n";
- }else{
- $tmp{$_}.=" not regular file or dir\n";
- }
- $tmp{$_}.="Owner: ".getpwuid($stat[4])." Group: ".getgrgid($stat[5])."\n";
- $tmp{$_}.="atime: ".&ctime($stat[8]);
- $tmp{$_}.="ctime: ".&ctime($stat[10]);
- }
- %tmp
- }
-
- sub give_a_clue1{
- local ($ans);
- system ("clear");
- print <<"HelpEnd";
- Gopher Environment Editor - Main Menu Help
-
- All commands must be followed by a carriage return
- At the main menu of items you can enter the following commands:
-
- [number] view item stat info and .cap/.link/.name info, if any
- c change to directory [number]
- h This help section
- f forward page or same page at end
- b back a page or same page at beginning
- q quit
- !command execute command in current dir
-
- HelpEnd
- print "\n<CR> to continue >";
- $ans=<STDIN>;
- }
-
- sub view_lead{
- local($key) = @_;
- local(@text)=();
- system ("clear");
- defined($files{$key}) ? (@finfo=split(/\n/,$files{$key})):(@finfo=("None"));
- defined($caps{$key}) ? (@cinfo=split(/\n/,$caps{$key})):(@cinfo=("None"));
- defined($links{$key}) ? (@linfo=split(/\n/,$links{$key})):(@linfo=("None"));
- @lines=("Stat info: ",@finfo,'', ".cap file info:",@cinfo,'',".link or .name file info:",@linfo);
- local($i,$tmp);
- $header=substr($key,0,30);
- print "Displayed Info: $header\n\n";
- for (@lines){
- print "$_\n";
- }
- print "\nEnter selection key, or h for help, or <CR> to return to main menu > ";
- $ans=<STDIN>;
- &do_sumthin($ans,$key);
- $ans=~/^[EeDdMm]/ && (return -1);
- }
-
- sub do_sumthin{
- local($ans,$key)=@_;
- if($ans =~ /^[Dd]/){
- &delete_file($key);
- }elsif($ans =~ /^[Ee]/){
- &change_display($key);
- }elsif($ans =~ /^[Hh]/){
- &give_a_clue2;
- }elsif($ans =~ /^[Mm]/){
- &mv_file($key);
- }elsif($ans =~ /^[Vv]/){
- &view_file($key);
- }
- }
-
- sub view_file{
- local ($key)=@_;
- system("$pager $key");
- }
-
- sub mv_file{
- local ($key)=@_;
- local($d,$newdir);
- system ("clear");
- print "\n\nThe following selections are available:\n\n";
- print "1> $mv $key to another directory\n";
- print "2> $cp $key to another directory\n";
- print "3> $ln $key to another directory\n";
- print "4> Forget about this altogther.\n\n";
- print "Select the number of your choice > ";
- chop($ans=<STDIN>);
- (($ans>3)||($ans <1)) && (print "aborting\n") && (return);
- ($ans==1) && ($com = $mv);
- ($ans==2) && ($com = $cp);
- ($ans==3) && ($com = $ln);
-
- if(-T $key){
- print "View file $key now? (y|n) > ";
- chop($tmp=<STDIN>);
- ($tmp=~/^[Yy]/) && &view_file($key);
- }
- print "Enter new dir for $key from toplevel";
- ($using_dir_list) ? (print ", ? to use selector\n > "):(print "\n > ");
- chop($d=<STDIN>);
-
- if($using_dir_list){
- ($d =~ /^\s*[?]/) && ($d=&select_dir) && ($d=~s/^\/?(.*)\/?$/$1/);
- $newdir=$toplevel.$d;
- system ("clear");
- print "\n$com $key to $newdir/$key ? (y|n) > ";
- $ans=<STDIN>;
- ($ans=~/^[Nn]/) && return;
- if(-d $newdir){
- system("$com $key $newdir/$key");
- }else{ print "Dir $d does not exist\n"; }
- }else{
- $newdir=$toplevel.$d;
- system ("clear");
- print "\n$com $key to $newdir/$key ? (y|n) > ";
- $ans=<STDIN>;
- ($ans=~/^[Nn]/) && return;
- if(-d $newdir){
- system("$com $key $newdir/$key");
- }else{ print "Dir $d does not exist"; }
- }
-
- }
-
- sub delete_file{
- local ($key)=@_;
- system("clear");
- local($summary,$done);
- print "Are you sure you want to delete this file? (Y|N) >";
- $summary=<STDIN>;
- if($summary=~/^[Yy]/){
- system("$rm $key");
- $! && do (print "not deleted\n" && return);
- print "deleted...\n" ;
- return;
- }
- print "not deleted...\n";
- sleep 1;
- }
-
- sub give_a_clue2{
- local ($ans);
- system ("clear");
- print <<"HelpEnd";
- Gopher Environment Editor - File Info Help
-
- All commands must be followed by a carriage return
- While viewing info on an item you can enter the following commands:
-
- d delete this file from the archive
- e change/create displayed info for this item
- h This help section
- v view this file
- m mv, cp, or ln this file somewhere else [use dir list]
-
- HelpEnd
- print "\n<CR> to continue >";
- $ans=<STDIN>;
- }
-
- sub change_display{
- local($f)=@_;
- local($name,$type,$path,$host,$port,$numb,$status);
- if(-T $f){
- print "View file $f now? (y|n) > ";
- chop($tmp=<STDIN>);
- ($tmp=~/^[Yy]/) && &view_file($f);
- }
- if(defined($links{$f})){
- ($file)=split('\n',$links{$f});
- print "Edit the link $f in $file now? (y|n) > ";
- $ans=<STDIN>;
- $ans =~ /[Nn]/ && return;
- system("$ed $file");
- print "Did you make changes? (y|n) > ";
- $ans=<STDIN>;
- $ans =~ /[Nn]/ && return;
- &nuke_cache || die "cant nuke the .cache file\n";
- return;
- }else{
- ($name,$type,$path,$host,$port,$numb,$status)=&parsef($f);
- $type=&get_type($type);
- if(defined($caps{$f})){
- ($name,$type,$path,$host,$port,$numb,$status)=
- &parse($caps{$f},$name,$type,$path,$host,$port,$numb,$status);
- print "File already has a .cap entry, overwrite? (y|n) > ";
- chop($ans=<STDIN>);
- if($ans =~ /^[Nn]/){
- print "Edit the .cap file for $f? (y|n) > ";
- chop($ans=<STDIN>);
- $ans =~ /^[Nn]/ && return;
- system("$ed" , ".cap\/$f");
- print "Did you make changes? (y|n) > ";
- $ans=<STDIN>;
- $ans =~ /[Nn]/ && return;
- &nuke_cache || die "cant nuke the .cache file\n";
- return;
- }
- }
- $ans="n";
- while($ans !~ /^[Yy]/){
- print "Enter Displayed name for item: [$name] \n> ";
- chop($tmp=<STDIN>);
- (length($tmp) > 0) && ($name=$tmp);
- if(defined($numb)){
- print "Enter Numb for file: [$numb]\n> ";
- chop($tmp=<STDIN>);
- (length($tmp) > 0) && ($numb=$tmp);
- }
- print "Enter Type for file: [$type]\n> ";
- chop($tmp=<STDIN>);
- (length($tmp) > 0) && ($type=$tmp);
- print "Enter Host for file: [$host]\n> ";
- chop($tmp=<STDIN>);
- (length($tmp) > 0) && ($host=$tmp);
- print "Enter Port for file: [$port]\n> ";
- chop($tmp=<STDIN>);
- (length($tmp) > 0) && ($port=$tmp);
- print "Use a \"Path=\" entry for this item? (y|n) > ";
- $tmp=<STDIN>;
- if($tmp=~/^[Yy]/){
- print "Enter Path for file: [$type/$path]\n> ";
- chop($p=<STDIN>);
- (length($p) > 0) && ($path=$p);
- $path=~s/\s*$//;
- }
- $entry="Name=$name\n";
- if(defined($numb)){
- $entry.="Numb=$numb\n";
- }
- $entry.="Type=$type\n";
- if($tmp=~/^[Yy]/){
- $entry.="Path=$type/$path\n";
- }
- $entry.="Host=$host\nPort=$port\n";
- print "\n$entry\n\n"."This look ok? (y|n) > ";
- $ans=<STDIN>;
- }
- system ("clear");
- print $entry."\n\n\n";
- print "1> Create this .cap file\n";
- print "2> Append this entry to $names file\n";
- print "3> Forget this entry\n";
- print "Select the number of your choice > ";
- chop($ans=<STDIN>);
- if($ans==1){
- &nuke_cache || die "cant nuke the .cache file\n";
- (-d ".cap") || mkdir(".cap",0755) || die "cant create .cap dir\n";
- open(CAP,">.cap/$f")||die "cant open the .cap file";
- print CAP $entry;
- close CAP;
- }elsif($ans==2){
- &nuke_cache || die "cant nuke the .cache file\n";
- open(NAMES,">>$names")||die "cant open $names\n";
- print NAMES "\n$entry\n";
- close NAMES;
- }
- }
- }
-
-
- sub parsef{
- local($name)=@_;
- local(@l,$type,$path,$host,$port,$numb,$status);
- $status='OK';
- $numb=undef;
- $port=$def_port;
- @l=split('\n',$files{$name});
- ($path,$type) = split(':',$l[0]);
- $path=~s/\s*$//;
- $host=$thishost;
- $files{$name} =~ /(ERROR)/ && ($status=$1);
- ($name,$type,$path,$host,$port,$numb,$status);
- }
-
-
- sub parse{
- local($entry,$name,$type,$path,$host,$port,$numb,$status)=@_;
- local($gotit);
- $entry =~ /Name=(.*)\s*\n{1,1}/ && ($name=$1);
- $entry =~ /Type=(.*)\s*\n{1,1}/ && ($type=$1);
- $entry =~ /Path=([\dm])?(.*)\s*\n{1,1}/ && ($type=$1,$path=$2,$gotit=1);
- $entry =~ /Host=(.*)\s*\n{1,1}/ && ($host=$1);
- $entry =~ /Port=(.*)\s*\n{1,1}/ && ($port=$1);
- $entry =~ /Numb=(.*)\s*\n{1,1}/ && ($numb=$1);
- if(($host eq "undefined")||($host eq "+")||($host eq "$thishost")){
- $tmp = $toplevel.$path;
- (-e $tmp) && $gotit && ($path=~s/.*\/(.*)/$1/);
- }
- $entry =~ /(ERROR)/ && ($status=$1);
- ($name,$type,$path,$host,$port,$numb,$status);
- }
-
- sub nuke_cache{
- (-f ".cache") && (unlink(".cache") || return 0);
- return 1;
- }
- sub do_new_cache{
- (-f ".cache") && unlink(".cache") || die "you cant do that";
- }
- sub get_type{
- local($type)=@_;
- local($tmp)=$type;
- ($type =~ /^\s*D/) && ($tmp=1);
- ($type =~ /^\s*T/) && ($tmp=0);
- $tmp;
- }
-
- sub select_dir{
- system("clear");
- local(@b)=();
- local(@text)=();
- local($key);
- $title='Select preferred directory';
- $footer='b = back a page, /[keyword] = search';
- local($i,$j);
- local(@win)=(1,22,79,1,0,7,$title,$footer);
- &win'title(@win);
- &win'footer(@win);
- @b= sort (keys(%dirs));
- for ($i=0,$j=0;$i <= $#b;$i++,$j++){
- if($j==$plen){ # buffer full, refresh screen
- &win'refresh(scalar(@text),@text,scalar(@win),@win);
- $tmp=&win'getdata(1,23,"select dir number or <CR> for more >",7);
- ($tmp =~ /^\d/) && (defined($b[$tmp])) && (return($b[$tmp]));
- if(($tmp =~ /^\/(.*)\n?$/) && ($key = $1)){
- $tmp2=$i;
- for(;$i <= $#b;$i++){
- last if ($b[$i] =~ /$key/);
- if($i>=$#b){
- &win'getdata(1,23,"Not Found, <CR> to continue >",7);
- $i=$tmp2;
- last;
- }
- }
- }elsif($tmp =~ /^[Bb]/){
- $i -= (2*$plen);
- }
- $j=0;
- $text[$j] = "$i> $b[$i]";
- }else{
- $text[$j] = "$i> $b[$i]";
- }
- }
- @text[$j..$plen]=();
- &win'refresh(scalar(@text),@text,scalar(@win1),@win1);
- $tmp=&win'getdata(1,23,"select dir number or <CR> to return >",7);
- ($tmp =~ /^\d/) && (defined($b[$tmp])) && (return($b[$tmp]));
- return ('.');
- }
-